import { compileToFunction } from "./compile/index";
import { initState } from "./initState";
import { mountComponent, callHook } from "./lifecycle";
import { mergeOptions } from "./utils/index";

// 模块化，抽取初始数据
export function initMixin(Vue) {
    Vue.prototype._init = function (options) {
        // console.log("初始化...", options);
        // --------------------------------------------------------------

        // 这里的this指向Vue的实例，可以在构造函数中打印一个对比，在vm上挂在属性更直观
        // 原型链的方法是实例调用的
        let vm = this
        // 把接收的参数挂载到vm上
        vm.$options = options
        // --------------------------------------------------------
        // 把混入的数据和new Vue传递的数据合并
        // console.log(Vue.$options);
        vm.$options = mergeOptions(options, Vue.options)
        // 调用生命周期方法beforeCreate
        callHook(vm, "beforeCreate")

        // 依次解析options中的每个选项
        // 初始化状态，这里传递vm合适，不要传递options，因为后面有一个this指向需要指向Vue，就是使用这个vm来实现的
        initState(vm)
        // 调用生命周期方法created
        callHook(vm, "created")
        // ------------------------------------------------------------
        // 渲染模板
        if (options.el) {
            vm.$mount(options.el)
        }
        // --------------------------------------------------------------------
    }
    // -----------------------------------------------------------------
    // 获取盒子的id，找到div容器，解析里面的vue语法
    Vue.prototype.$mount = function (el) {

        let vm = this
        // 根据id查找dom
        el = document.querySelector(el)

        // 保留旧的dom
        vm.$el = el
        let options = vm.$options

        // 如果没有定义render函数
        if (!options.render) {
            let template = options.template

            // 只有el
            if (!template && el) {
                // 获取html  // <div id="app">{{school}}</div>
                el = el.outerHTML

                // 得到render函数
                let render = compileToFunction(el)
                // console.log(el);

                // 把render函数字符串挂载到vm的$options属性中，后面获取需要
                vm.$options.render = render

            }
        }

        // 挂在组件，完成虚拟dom的生成，挂载_c,_v,_s,_render
        mountComponent(vm, el)
    }
}